package com.zui.webapp.support;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.HttpServletBean;

import com.zui.entity.BaseEntity;
import com.zui.entity.product.Catalog;
import com.zui.entity.product.Feature;
import com.zui.entity.product.FeatureType;
import com.zui.entity.product.ProductFeatureApplType;
import com.zui.entity.product.ProductType;
import com.zui.entity.product.ShipmentBoxType;
import com.zui.entity.setup.UomType;
import com.zui.manager.SessionManager;
import com.zui.util.ZuiConstants;

/**
 * 
 * @author Sam
 * @since 1.0
 */
public class DataCacheInitServlet extends HttpServletBean {

	private static final long serialVersionUID = 1L;

	ServletContext context = null;
	SessionManager sessionMgr = null;

	@Override
	protected void initServletBean() throws ServletException {
		ApplicationContext ctx = WebApplicationContextUtils
				.getRequiredWebApplicationContext(this.getServletContext());
		context = this.getServletContext();
		sessionMgr = (SessionManager) ctx.getBean("sessionManager");
			initDataCache();
	}

	/**
	 * database population with dbunit
	 * 
	 */
	@Override
	protected final void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		initDataCache();
		/**
		 * @TODO:wirte success response.
		 */

	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void initDataCache() {

		//Prepare the first level catalog list
		prepareCatalogList();

		//Prepare the select map
		Map<String, Object> selectYesNo = new LinkedHashMap<String, Object>();
		selectYesNo.put(BaseEntity.FLAG_Y, "Yes");
		selectYesNo.put(BaseEntity.FLAG_N, "No");
		context.setAttribute(ZuiConstants.SELECT_YES_NO, selectYesNo);

		//Prepare the select map		
		Map<String, Object> selectProductType = new LinkedHashMap<String, Object>();
		//selectYesNo.put(ZuiConstants.STATUS_YES, "Yes");			
		List<ProductType> ptList = sessionMgr.loadAll(ProductType.class);
		if (ptList!=null) {
			Iterator<ProductType> it = ptList.iterator();
			while (it.hasNext()) {
				ProductType pt = it.next();
				selectProductType.put(pt.getId(), pt.getName());
			}
			context.setAttribute(ZuiConstants.SELECT_PRODUCT_TYPE, selectProductType);
		}
		
		//Prepare the uom type select map
		Map<String, Object> selectUomType = new LinkedHashMap<String, Object>();	
		List<UomType> utList = sessionMgr.loadAll(UomType.class);
		if (utList!=null) {
			Iterator<UomType> it = utList.iterator();
			while (it.hasNext()) {
				UomType pt = it.next();
				selectUomType.put(pt.getId(), pt.getUomTypeName());
			}
			context.setAttribute(ZuiConstants.SELECT_UOM_TYPE, selectUomType);
		}
		
		//Prepare the shipment box type select map
		Map<String, Object> selectShipmentBoxType = new LinkedHashMap<String, Object>();
						
		List<ShipmentBoxType> sbtList = sessionMgr.loadAll(ShipmentBoxType.class);
		if (sbtList!=null) {
			Iterator<ShipmentBoxType> it = sbtList.iterator();
			while (it.hasNext()) {
				ShipmentBoxType pt = it.next();
				selectShipmentBoxType.put(pt.getShipmentBoxTypeId(), pt.getShipmentBoxTypeName());
			}
			context.setAttribute(ZuiConstants.SELECT_SHIPMENT_BOX_TYPE, selectShipmentBoxType);
		}

		//Prepare the feature type select map
		Map<String, Object> selectFeatureType = new LinkedHashMap<String, Object>();
		Map<Object, Map> doubleSelectFeature = new LinkedHashMap<Object, Map>();
						
		List<FeatureType> ftList = sessionMgr.loadAll(FeatureType.class);
		if (ftList!=null) {
			Iterator<FeatureType> it = ftList.iterator();
			
			while (it.hasNext()) {
				FeatureType pt = it.next();
				selectFeatureType.put(pt.getId(), pt.getName());
				
				Map<Object, Object> doubleSelectFeatureMap = new LinkedHashMap<Object, Object>();					
				Iterator<Feature> itFeature = pt.getFeatures().iterator();
				while (itFeature.hasNext()) {
					Feature feature = itFeature.next();
					doubleSelectFeatureMap.put(feature.getId(), feature.getName());
				}
				doubleSelectFeature.put(pt.getId(), doubleSelectFeatureMap);
			}
			context.setAttribute(ZuiConstants.SELECT_FEATURE_TYPE, selectFeatureType);
			context.setAttribute(ZuiConstants.DOUBLE_SELECT_FEATURE, doubleSelectFeature);
			context.setAttribute(ZuiConstants.DOUBLE_SELECT_FEATURE_JQUERY, JsonDataHelper.getDoubleSelctJson(selectFeatureType, doubleSelectFeature));
		}

		
		//Prepare the SELECT_PRODUCT_FEATURE_APPL_TYPE select map
		Map<String, Object> selectProductFeatureApplType = new LinkedHashMap<String, Object>();
					
		List<ProductFeatureApplType> pfaList = sessionMgr.loadAll(ProductFeatureApplType.class);
		if (pfaList!=null) {
			Iterator<ProductFeatureApplType> it = pfaList.iterator();
			while (it.hasNext()) {
				ProductFeatureApplType pt = it.next();
				selectProductFeatureApplType.put(pt.getId(), pt.getName());
			}
			context.setAttribute(ZuiConstants.SELECT_PRODUCT_FEATURE_APPL_TYPE, selectProductFeatureApplType);
		}
		
		
//		if (logger.isDebugEnabled())
//			logger.debug("Loaded " + dataSetCount
//					+ " dataset xml files from location pattern ["
//					+ datasetLocation + "]");
	}
	

	private void prepareCatalogList() {
		DetachedCriteria criteria = DetachedCriteria.forClass(Catalog.class);
		criteria.add(Restrictions.eq("isDeleted", BaseEntity.FLAG_N));
		Set<Catalog> catalogSet = new LinkedHashSet<Catalog>(sessionMgr.findByCriteria(criteria));
		context.setAttribute(ZuiConstants.CATALOG_SET, catalogSet);
	}

	/**
	 * 
	 * @return
	 */
	public String getDoubleSelctJQueryOptions(Map firstMap, Map<Object, Map> secondMap) {
//		 $(document).ready(function()
//				 {
//				    	    "Vegetables": {
//				    	         "key" : 10,
//				                 "defaultvalue" : 111,
//				    	         "values" : {
//				                     "tomato": 110,
//				                     "potato": 111,
//				                     "asparagus": 112
//				                     }
//				              },
//				            "Fruits": {
//				                 "key" : 20,
//				                 "defaultvalue" : 212,
//				                 "values" : {
//				                     "apple": 210,
//				                     "orange": 211,
//				                     "kiwi": 212,
//				                     "melon": 213
//				                     }
//				              }
//				    };
		
		StringBuffer optionsBuf = new StringBuffer(); 
		Set keySet = firstMap.keySet();
		Iterator keySetIt = keySet.iterator();
		while (keySetIt.hasNext()) {
			Object key = keySetIt.next();
			optionsBuf.append("\"" + firstMap.get(key) + "\":" + "{");
			
			Map doubleMap = secondMap.get(key);
			Set doubleKeySet = doubleMap.keySet();
			
			Iterator doubleKeySetIt = doubleKeySet.iterator();
			optionsBuf.append("\"key\":" + "\"" + key + "\",");
			optionsBuf.append("\"values\": {" );
			
			while (doubleKeySetIt.hasNext()) {
				Object doubleKey = doubleKeySetIt.next();
				optionsBuf.append("\"" + doubleMap.get(doubleKey) + "\":\"" + doubleKey + "\",");
			}
			if (!doubleKeySet.isEmpty())
				optionsBuf.deleteCharAt(optionsBuf.lastIndexOf(","));
			optionsBuf.append("}" );
			optionsBuf.append("}," );
		}
		if (!keySet.isEmpty())
			optionsBuf.deleteCharAt(optionsBuf.lastIndexOf(","));
		return optionsBuf.toString();
	}

}
